package org.databasefacade.table;


import java.util.ArrayList;

import org.databasefacade.exception.DatabaseFacadeException;
import org.databasefacade.table.column.AliasedColumnList;
import org.databasefacade.table.column.Column;


public class ConstraintKey
{
	protected boolean isPrimaryKey = false;
	protected AliasedColumnList columns;
	protected String foreignTableName = null;
	protected ArrayList foreignColumnNames = new ArrayList();
	
	/**
	 * Used internally by the class to create a copy
	 */
	private ConstraintKey()
	{}
	
	/**
	 * Create a single column primary key. Once
	 * it is constructed this key can be extended
	 * to become a composite primary key.
	 * 
	 * @param col
	 */
	public ConstraintKey(Column col)
	{
		isPrimaryKey = true;
		columns = new AliasedColumnList(col.getTranslator());
		columns.addAliasedColumn(col);
	}
	
	/**
	 * Create a single column foreign key. Once
	 * it is constructed this key can be extended
	 * to become a composite foreign key.
	 * 
	 * @param col
	 * @param foreignTableName
	 */
	public ConstraintKey(Column col, String foreignTableName)
	{
		this.isPrimaryKey = false;
		columns = new AliasedColumnList(col.getTranslator());
		this.columns.addAliasedColumn(col);
		this.foreignTableName = foreignTableName;
		this.foreignColumnNames.add(col.getColumnName());
	}
	
	public ConstraintKey(Column col, String foreignTableName, String foreignColumnName)
	{
		this.isPrimaryKey = false;
		columns = new AliasedColumnList(col.getTranslator());
		this.columns.addAliasedColumn(col);
		this.foreignTableName = foreignTableName;
		this.foreignColumnNames.add(foreignColumnName);
	}
	
	public void addCompositePrimaryColumn(Column col)
		throws DatabaseFacadeException
	{
		if ( isForeignKey() ) {
			throw new DatabaseFacadeException(
				"Cannot add composite primary components to foreign key.");
		}
		columns.addAliasedColumn(col);
	}
	
	public void addCompositeForeignColumn(Column col)
		throws DatabaseFacadeException
	{
		addCompositeForeignColumn(col, col.getColumnName());
	}
	
	public void addCompositeForeignColumn(
		Column col, 
		String foreignColumnName)
		throws DatabaseFacadeException
	{
		if ( isPrimaryKey() ) {
			throw new DatabaseFacadeException(
				"Cannot add composite foreign components to primary key.");
		}
		columns.addAliasedColumn(col);
		foreignColumnNames.add(foreignColumnName);
	}
	
	public boolean isPrimaryKey()
	{
		return isPrimaryKey;
	}
	
	public boolean isForeignKey()
	{
		return (!isPrimaryKey());
	}
	
	public boolean isCompositeKey()
	{
		return (columns.size() > 1);
	}
	
	public String getForeignTableName()
	{
		return foreignTableName;
	}
	
	public AliasedColumnList getKeyColumns()
	{
		return columns;
	}
	
	public String getForeignKeyColumnName(int i)
	{
		return (String) foreignColumnNames.get(i);
	}
	
	public void addKeyColumn(Column column)
	{
		columns.addAliasedColumn(column);
	}
	
	public ConstraintKey getCopy()
	{
		ConstraintKey newKey = new ConstraintKey();
		newKey.isPrimaryKey = this.isPrimaryKey;
		for ( int i = 0; i < columns.size(); i++ ) {
			newKey.columns.addAliasedColumn(this.columns.getColumn(i).getCopy());
		}
		if ( foreignTableName != null ) {
			newKey.foreignTableName = new String(foreignTableName);
			for ( int i = 0; i < foreignColumnNames.size(); i++ ) {
				newKey.foreignColumnNames.add(
					new String((String) this.foreignColumnNames.get(i)));
			}
		}
		return newKey;
	}
}
